#include "MGUI_Layout.h"
#include "MGUI_Helper.h"
#include "MGUI_Engine.h"

namespace Myway {

	ImplementRTTI(MGUI_Layout, MGUI_Widget);

	MGUI_Layout::MGUI_Layout(const MGUI_LookFeel * _lookfeel, MGUI_Widget * _parent)
		: MGUI_Widget(_lookfeel, _parent)
	{
		if (mParent == NULL)
			MGUI_Engine::Instance()->AddLayout(this);
	}

	MGUI_Layout::~MGUI_Layout()
	{
		if (mParent == NULL)
			MGUI_Engine::Instance()->RemoveLayout(this);
	}

	MGUI_RenderItem * MGUI_Layout::GetRenderItem(int _order, Texture * _skin)
	{
		List<MGUI_RenderItem *>::Iterator whr = mRenderItems.Begin();
		List<MGUI_RenderItem *>::Iterator end = mRenderItems.End();

		while (whr != end)
		{
			MGUI_RenderItem * item = *whr;

			if (item->GetOrder() == _order
				&& item->GetTexture() == _skin)
				return item;

			++whr;
		}

		whr = mRenderItems.Begin();
		while (whr != end)
		{
			MGUI_RenderItem * item = *whr;

			if (item->GetOrder() > _order)
			{
				item = MGUI_Helper::Instance()->GetEmptyRenderItem(_order, _skin);

				mRenderItems.Insert(whr, item);

				return item;
			}

			++whr;
		}

		{
			MGUI_RenderItem * item = MGUI_Helper::Instance()->GetEmptyRenderItem(_order, _skin);

			mRenderItems.PushBack(item);

			return item;
		}
	}

	void MGUI_Layout::UpdateRenderItem()
	{
		List<MGUI_RenderItem *>::Iterator whr = mRenderItems.Begin();
		List<MGUI_RenderItem *>::Iterator end = mRenderItems.End();

		while (whr != end)
		{
			(*whr)->Reset();

			++whr;
		}

		mRenderItems.Clear();

		MGUI_Widget::UpdateRenderItem(this);
	}

	void MGUI_Layout::DoRender()
	{
		List<MGUI_RenderItem *>::Iterator whr = mRenderItems.Begin();
		List<MGUI_RenderItem *>::Iterator end = mRenderItems.End();

		while (whr != end)
		{
			MGUI_RenderItem * item = *whr;

			item->DoRender();

			++whr;
		}
	}



	MGUI_Layout * MGUI_LayoutLoader::Load(const char * source, MGUI_Widget * parent)
	{
		DataStreamPtr stream = ResourceManager::Instance()->OpenResource(source);

		if (stream == NULL)
		{
			LOG_PRINT_FORMAT("Error: Layout file '%s' can't open.\n", source);
			return NULL;
		}

		return Load(stream, parent);
	}

	MGUI_Layout * MGUI_LayoutLoader::Load(DataStreamPtr stream, MGUI_Widget * parent)
	{
		xml_doc doc;

		XmlHelper::LoadXmlFromMem(doc, (char *)stream->GetData());

		xml_node * node = doc.first_node("Layout");

		if (node == NULL)
			return NULL;

		MGUI_Layout * layout = new MGUI_Layout(NULL, parent);

		_loadWidget(layout, node);

		return layout;
	}

	void MGUI_LayoutLoader::_loadWidget(MGUI_Widget * _widget, xml_node * _node)
	{
		_widget->LoadXml(_node);

		xml_node * child = _node->first_node("Child");

		while (child)
		{
			TString128 typeString = child->first_attribute("type")->value();
			TString128 lkString = child->first_attribute("lookfeel")->value();

			int type = MGUI_WidgetType::GetType(typeString);
			const MGUI_LookFeel * lookfeel = lkString != "" ? MGUI_LookFeelManager::Instance()->GetLookFeel(type, lkString) : NULL;

			MGUI_Widget * childWidget = MGUI_Helper::Instance()->CreateWidget(type, lookfeel, _widget);

			_loadWidget(childWidget, child);

			child = child->next_sibling("Child");
		}
	}

}

